<?php

namespace App\Logics;

// 导入七牛相关类
use App\Service\AliyunSMS;
use App\Service\BaiduCensor;
use App\Service\Base\Logic;
use App\Service\Image;
use Illuminate\Support\Facades\Config;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;

class UploadFile extends Logic
{

    // 上传文件：上传本地 + 压缩
    public function image()
    {
        $opt  = $this->option();
        $_is  = $opt->getData('is_compress');
        $file = $opt->request()->file('file');
        //$path = $file->store('images');
        if(!$file->isValid()){
            return $this->_returnFail($file->getError());
        }

        // 缓存在tmp文件夹中的文件名 例如 php8933.tmp 这种类型的.
        $clientName = $file->getClientOriginalName();
        $tmpName    = $file->getFileName();
        // 这个表示的是缓存在tmp文件夹下的文件的绝对路径(这里要注意,如果我使用接下来的move方法之后, getRealPath() 就找不到文件的路径了.因为文件已经被移走了.所以这里道出了文件上传的原理,将文件上传的某个临时目录中,然后使用Php的函数将文件移动到指定的文件夹.)
        $realPath = $file->getRealPath();
        // 上传文件的后缀.
        $entension = $file->getClientOriginalExtension();
        // 大家对mimeType应该不陌生了. 我得到的结果是 image/jpeg.(这里要注意一点,以前我们使用 mime_content_type() ,在php5.3 之后,开始使用 fileinfo 来获取文件的mime类型.所以要加入 php_fileinfo的php拓展.windows下是 php_fileinfo.dll,在php.ini文件中将 extension=php_fileinfo.dll前面的分号去掉即可.当然要重启服务器. )
        $mimeTye = $file->getMimeType();
        // (第一种)最后我们使用
        $newName  = md5(date("Y-m-d H:i:s").$clientName).".".$entension;
        $path     = 'storage/uploads/'.date("Ym").'/'.date('d');
        $local    = '/'.date("Ym").'/'.date('d'); // 上传到本地目录 上个的单独域名访问
        $path     = '../../cdn'.$local; // 上传到本地目录
        $res      = $file->move($path, $newName);
        $filePath = $path.'/'.$newName;
        // 如果你这样写的话,默认是会放置在 我们 public/storage/uploads/
        // $path = $file -> move(app_path().'/storage/uploads',$newName);
        // 这里app_path()就是app文件夹所在的路径.$newName 可以是你通过某种算法获得的文件的名称.主要是不能重复产生冲突即可. 比如 $newName = md5(date("Y-m-d H:i:s").$clientName).".".$entension;

        // 图片截取
        $image  = Image::open($filePath);
        $width  = $image->width();  // 返回图片的宽度
        $height = $image->height();  // 返回图片的高度
        // 压缩
        if($_is){
            $toWidth = 800;
            if($width > $toWidth){
                $toHeight = $height * $width / $toWidth;
                $size     = $image->thumb($toWidth, $toHeight)->save($filePath);
            } else{
                //
                $size = $image->thumb($width, $height)->save($filePath);
            }
        }


        // 缩略图
        $toWidth = 200;
        if($width > $toWidth){
            $toHeight  = $height * $width / $toWidth;
            $thumbPath = $filePath.".150px.".$entension;
            $size      = $image->thumb($toWidth, $toHeight)->save($thumbPath);
        }
        // 组合域名地址
        $domain = Config::get('site.cdnHost');
        if(substr($domain, -1) == '/'){
            $domain = substr($domain, 0, -1);
        }
        $src = $domain.$local.'/'.$newName;

        return $src;
    }

    // 上传文件
    // 上传文件 现在使用上传在本地
    public function file()
    {
        $opt  = $this->option();
        $_is  = $opt->getData('is_compress');
        $file = $opt->request()->file('file');
        //$path = $file->store('images');
        if(!$file->isValid()){
            return $this->_returnFail($file->getError());
        }

        // 缓存在tmp文件夹中的文件名 例如 php8933.tmp 这种类型的.
        $clientName = $file->getClientOriginalName();
        $tmpName    = $file->getFileName();
        // 这个表示的是缓存在tmp文件夹下的文件的绝对路径(这里要注意,如果我使用接下来的move方法之后, getRealPath() 就找不到文件的路径了.因为文件已经被移走了.所以这里道出了文件上传的原理,将文件上传的某个临时目录中,然后使用Php的函数将文件移动到指定的文件夹.)
        $realPath = $file->getRealPath();

        // 验证图片后缀
        $entension = strtolower($file->getClientOriginalExtension());  // 上传文件的后缀.
        $images    = ['bmp', 'dib', 'pcp', 'dif', 'wmf', 'jpg', 'tif', 'eps', 'cdr', 'iff', 'tga', 'pcd', 'mpt', 'png', 'jpeg', 'psd', 'tiff', 'bnp']; // 'gif',
        $voices    = ['mp3', 'wav', 'wma', 'mp2', 'flac', 'midi', 'ra', 'ape', 'aac', 'cda', 'mov', 'rar'];
        if($entension == 'gif'){
            return $this->_returnFail('请不要上传gif文件！！');
        }

        $is_pic   = in_array($entension, $images);
        $is_voice = in_array($entension, $voices);
        if((!$is_pic) && (!$is_voice)){
            return $this->_returnFail('请上传正确的文件格式！！');
        }

        // 获取文件内容 在百度验证
        if($is_pic){
            //$content = $file->getContent();
            //$opt->baiduImageCensor($realPath); // 百度审核，两种传值都可以
            $opt->baiduImageCensor($file); // 百度审核，两种传值都可以
        }
        if($is_voice){
            $res = $opt->baiduVoiceCensor($file); // 百度审核，语音审核
            // 语音的文本
            $voiceText = $res['rawText'];
        }


        // 大家对mimeType应该不陌生了. 我得到的结果是 image/jpeg.(这里要注意一点,以前我们使用 mime_content_type() ,在php5.3 之后,开始使用 fileinfo 来获取文件的mime类型.所以要加入 php_fileinfo的php拓展.windows下是 php_fileinfo.dll,在php.ini文件中将 extension=php_fileinfo.dll前面的分号去掉即可.当然要重启服务器. )
        $mimeTye = $file->getMimeType();

        // (第一种)最后我们使用
        $newName  = md5(date("Y-m-d H:i:s").$clientName).".".$entension;
        $path     = 'storage/uploads/'.date("Ym").'/'.date('d');
        $local    = '/'.date("Ym").'/'.date('d'); // 上传到本地目录 上个的单独域名访问
        $path     = '../../cdn'.$local; // 上传到本地目录
        $res      = $file->move($path, $newName);
        $filePath = $path.'/'.$newName;
        // 如果你这样写的话,默认是会放置在 我们 public/storage/uploads/
        // $path = $file -> move(app_path().'/storage/uploads',$newName);
        // 这里app_path()就是app文件夹所在的路径.$newName 可以是你通过某种算法获得的文件的名称.主要是不能重复产生冲突即可. 比如 $newName = md5(date("Y-m-d H:i:s").$clientName).".".$entension;

        // 如果是图片
        if($is_pic){
            // 图片截取
            $image  = Image::open($filePath);
            $width  = $image->width();  // 返回图片的宽度
            $height = $image->height();  // 返回图片的高度
            // 压缩
            if($_is){
                $toWidth = 800;
                if($width > $toWidth){
                    //$toHeight = $height * $width / $toWidth;
                    $toHeight = $height * $toWidth / $width;
                    $size     = $image->thumb($toWidth, $toHeight)->save($filePath);
                } else{
                    //
                    $size = $image->thumb($width, $height)->save($filePath);
                }
            }
            // 缩略图
            $toWidth = 200;
            if($width > $toWidth){
                $toHeight = $height * $width / $toWidth;
                $filePath = $filePath.".150px.".$entension;
                $size     = $image->thumb($toWidth, $toHeight)->save($filePath);
            }
        }

        // 组合域名地址
        // 组合域名地址
        $domain = Config::get('site.cdnHost');
        if(substr($domain, -1) == '/'){
            $domain = substr($domain, 0, -1);
        }
        $src = $domain.$local.'/'.$newName;

        /*if($is_voice){
            return $this->success($src, '文件上传成功！！');
        } else{
            return $this->success(['src' => $src, 'text' => $voiceText,], '文件上传成功！！');
        }*/
    }

    // 上传七牛云（并压缩图片在上传）（自己直接调用七牛云插件）
    public function qiniu()
    {
        $opt  = $this->option();
        $_is  = $opt->getData('is_compress');
        $file = $opt->request()->file('file');
        if(!$file->isValid()){
            return $this->_returnFail($file->getError());
        }

        // 验证图片后缀
        //$entension = strtolower($file->getExtension());  // 上传文件的后缀.
        $entension = strtolower($file->getClientOriginalExtension());  // 上传文件的后缀.
        $images    = ['bmp', 'dib', 'pcp', 'dif', 'wmf', 'jpg', 'tif', 'eps', 'cdr', 'iff', 'tga', 'pcd', 'mpt', 'png', 'jpeg', 'psd', 'tiff', 'bnp']; // 'gif',
        $voices    = ['mp3', 'wav', 'wma', 'mp2', 'flac', 'midi', 'ra', 'ape', 'aac', 'cda', 'mov'];
        if(empty($entension)){
            $entension = 'jpg';
        }
        if($entension == 'gif'){
            return $this->_returnFail('请不要上传gif文件！！');
        }

        $is_pic   = in_array($entension, $images);
        $is_voice = in_array($entension, $voices);
        $fileName = $file->getPathname();
        if((!$is_pic) && (!$is_voice)){
            return $this->_returnFail('请上传正确的文件格式！！');
        }
        if(!$is_pic){
            return $this->_returnFail('请上传正确的文件格式！！');
        }

        // 获取文件内容 在百度验证
        if($is_pic){
            //$content = $file->getContent();
            //$opt->baiduImageCensor($realPath); // 百度审核，两种传值都可以
            $opt->baiduImageCensor($file); // 百度审核，两种传值都可以
        }
        /*if($is_voice){
            $res = $opt->baiduVoiceCensor($file); // 百度审核，语音审核
            // 语音的文本
            $voiceText = is_array($res['rawText']) ? implode('。', $res['rawText']) : $res['rawText'];
        }*/

        // 上传参数
        $to        = 'mini/'.date('Y/Ym/d/').date('Ymd').microtime(true).mt_rand().'.'.$entension;
        $qiUpload  = new UploadManager();
        $accessKey = config('filesystems.disks.qiniu.access_key');
        $secretKey = config('filesystems.disks.qiniu.secret_key');
        $bucket    = config('filesystems.disks.qiniu.bucket'); //上传空间名称

        // 上传
        $auth  = new Auth($accessKey, $secretKey);
        $token = $auth->uploadToken($bucket);
        $res   = $qiUpload->putFile($token, $to, $fileName, null, $file->getMimeType(), false);

        // 压缩 在上传
        /*if($is_pic){
            $to_local = $fileName.'_thumb.jpg';
            $to_to    = $to.'_thumb.jpg';
            $this->toCompress($fileName, $to_local);
            $res = $qiUpload->putFile($token, $to_to, $to_local, null, $file->getMimeType(), false);
        }*/

        // 组合域名地址
        $domain = Config::get('filesystems.disks.qiniu.domain');
        if(substr($domain, -1) != '/'){
            $domain = $domain.'/';
        }
        $to = $domain.$to;

        if($is_voice){
            //'voice_text' => $voiceText,
            //return $this->success(['src' => $to,], '文件上传成功！！');
        } else{
            //return $this->success(['src' => $to], '文件上传成功！！');
        }

        return $to;
    }

    // 上传七牛云（系统调用七牛云插件）
    public function qiniu2()
    {
        $opt  = $this->option();
        $_is  = $opt->getData('is_compress');
        $file = $opt->request()->file('file');
        if(!$file->isValid()){
            return $this->_returnFail($file->getError());
        }

        // 验证图片后缀
        $entension = strtolower($file->getClientOriginalExtension());  // 上传文件的后缀.
        $images    = ['bmp', 'dib', 'pcp', 'dif', 'wmf', 'jpg', 'tif', 'eps', 'cdr', 'iff', 'tga', 'pcd', 'mpt', 'png', 'jpeg', 'psd', 'tiff', 'bnp']; // 'gif',
        $voices    = ['mp3', 'wav', 'wma', 'mp2', 'flac', 'midi', 'ra', 'ape', 'aac', 'cda', 'mov'];
        if($entension == 'gif'){
            return $this->_returnFail('请不要上传gif文件！！');
        }

        $is_pic   = in_array($entension, $images);
        $is_voice = in_array($entension, $voices);
        if((!$is_pic) && (!$is_voice)){
            return $this->_returnFail('请上传正确的文件格式！！');
        }

        // 获取文件内容 在百度验证
        if($is_pic){
            //$content = $file->getContent();
            //$opt->baiduImageCensor($realPath); // 百度审核，两种传值都可以
            $opt->baiduImageCensor($file); // 百度审核，两种传值都可以
        }


        $to    = 'mini/'.date('Y/Ym/d/').date('Ymd').microtime(true).mt_rand().'.'.$entension;
        $time  = 'mini/'.date('Y/Ym/d');
        $disk  = \Storage::disk('qiniu'); //使用七牛云上传
        $_name = $disk->put($time, $file);//上传至七牛云
        if(!$_name){
            return $this->_returnFail("上传失败！");
        }

        //$img_url = '/'.$filename;
        // http://slh.caitongnews.com/2022-12-30/f8THIo9E76GyWkKUneqG7MMp6SnOPqCzO7EsjbTT.jpg
        $img_url = $disk->getDriver()->downloadUrl($_name); //获取下载链接 removePathPrefix

        return $img_url;
    }

    // 发送短信验证码（百度）
    public function sms()
    {
        $timeout = 60; // 超时时间 60秒
        $timeout = 6; // 超时时间 60秒
        $times   = 50; // 一个号一天限制10次
        // 参数检查
        $opt      = $this->option();
        $mobile   = $opt->getData('mobile');
        $isMobile = preg_match("/^1[3|4|5|6|7|8|9][0-9]\d{8}$/", $mobile);
        if(!$isMobile){
            return $this->_returnFail('请检查手机号码!!');
        }

        // 发送短信是否满了
        $smsDb = new SiteSms();
        $where = [["mobile", '=', $mobile], ["ctime", '>=', strtotime("today")]];
        $lists = $smsDb->bangField(['mobile'])->getList($where, 0, 'id DESC');
        $lists = is_object($lists) ? $lists->toArray() : $lists;
        // 验证
        // TODO 分送时间10分钟内有效。一个号一天限制10次
        // TODO 间隔时间 60s
        if($lists){
            if(count($lists) >= 10){
                return $this->_returnFail('超过当日可发条数！');
            }
            if($lists[0]['ctime'] >= LARAVEL_TIME - 60){
                return $this->_returnFail('一分钟后再试！');
            }
        }

        // sms-tmpl-asrGtf70927 验证码  code
        // sms-tmpl-UXmJiz55799 身份认证 name  content
        // sms-tmpl-jRdZOE16549 访谈预约 name
        //$mobile = 18086843363;
        //$mobile = 13981983854;
        $code = random(6);
        if(in_array($mobile, ['13541274252', '18227769478', '13541274252', '13981983854'])){
            $code = '123456';
        }
        $temp = 'sms-tmpl-asrGtf70927';
        $send = ['code' => $code];

        // 发送短信操作
        $res = $this->baiduSms($mobile, $temp, $send);
        if($res['code'] != 1000){
            return $this->_returnFail('短信发送失败！', $res);
        }
        try{
            $add = ["mobile" => $mobile, "code" => $code, "ip" => $opt->getIp(), "status" => "0", "ctime" => LARAVEL_TIME];
            $smsDb->oneAdd($add);
        } catch(\Exception $e){
            return $this->_returnFail($e->getMessage());
        }

        return $code;
    }

    // 发送短信验证码（阿里云）
    public function alisms()
    {
        // 阿里云短信秘钥
        $accessKeyId  = "LTAI4FdJDE5Q9kawRVZyV8H1";
        $accessSecret = "HRb6uHApdwJJDwzx7uchoSebUJcNJS";


        // 参数检查
        $opt      = $this->option();
        $mobile   = $opt->getData('mobile');
        $isMobile = preg_match("/^1[3|4|5|6|7|8|9][0-9]\d{8}$/", $mobile);
        if(!$isMobile){
            return $this->_returnFail('请检查手机号码!!');
        }


        $smsDb = new SiteSms();
        $where = [["mobile", '=', $mobile], ["ctime", '>=', strtotime("today")]];
        $lists = $smsDb->bangField(['mobile'])->getList($where, 0, 'id DESC');
        $lists = is_object($lists) ? $lists->toArray() : $lists;
        // 验证
        // TODO 分送时间10分钟内有效。一个号一天限制10次
        // TODO 间隔时间 60s
        if($lists){
            if(count($lists) >= 10){
                return $this->_returnFail('超过当日可发条数！');
            }
            if($lists[0]['ctime'] >= LARAVEL_TIME - 60){
                return $this->_returnFail('一分钟后再试！');
            }
        }

        // 发送短信信息
        $code   = random(6);
        $code   = 123456; // TODO 现在验证码默认是123456
        $params = [
            "PhoneNumbers"  => $mobile,
            "TemplateCode"  => "SMS_184616159",
            "SignName"      => "财通社",  // TODO 这是一个签名（不能随意修改）
            "TemplateParam" => json_encode(["code" => $code], JSON_UNESCAPED_UNICODE),
            "RegionId"      => "cn-hangzhou",
            "Action"        => "SendSms",
            "Version"       => "2017-05-25",
        ];
        $params = [
            "PhoneNumbers"  => $mobile,
            "TemplateCode"  => "SMS_200701934",
            "SignName"      => "深蓝财经",  // TODO 这是一个签名（不能随意修改）
            "TemplateParam" => json_encode(["code" => $code], JSON_UNESCAPED_UNICODE),
            "RegionId"      => "cn-hangzhou",
            "Action"        => "SendSms",
            "Version"       => "2017-05-25",
        ];

        // 发送短信请求执行
        $time = LARAVEL_TIME;
        $hash = new AliyunSMS();
        $ret  = $hash->request($accessKeyId, $accessSecret, "dysmsapi.aliyuncs.com", $params);
        if($ret["Message"] == "OK" || $ret["Code"] == "OK"){
        } else{
            return $this->_returnFail("发送失败！");
        }

        try{
            $add = ["mobile" => $mobile, "code" => $code, "ip" => $opt->getIp(), "status" => "0", "ctime" => $time];
            $smsDb->oneAdd($add);
        } catch(\Exception $e){
            return $this->_returnFail($e->getMessage());
        }

        return $code;
    }


    // 七牛云 自身的上传（上传到根目录）
    public function postDoupload()
    {
        $token    = $this->getToken();
        $manager  = new UploadManager();
        $name     = $_FILES['file']['name'];
        $filePath = $_FILES['file']['tmp_name'];
        $type     = $_FILES['file']['type'];

        list($ret, $err) = $manager->putFile($token, $name, $filePath, null, $type, false);
        if($err){
            return $this->_returnFail($err);
        }

        // 上传成功
        // key就是上传的图片，带上域名就可以正常访问
        /*{
            "hash": "FloHIv9blcUP8Iur4eNhe-5GoVV7",
		    "key": "1Z93012500LS5-0-lp.jpg"
	    }*/

        return $ret;
    }

    // 生成上传凭证
    protected function getToken()
    {
        $accessKey = config('filesystems.disks.qiniu.access_key');
        $secretKey = config('filesystems.disks.qiniu.secret_key');
        $auth      = new Auth($accessKey, $secretKey);
        $bucket    = config('filesystems.disks.qiniu.bucket');//上传空间名称

        //设置put policy的其他参数
        //$opts=['callbackUrl'=>'http://www.callback.com/','callbackBody'=>'name=$(fname)&hash=$(etag)','returnUrl'=>"http://www.baidu.com"];
        return $auth->uploadToken($bucket);//生成token
    }

}


